package com.rtx.wms.std.handler.transfer.down;

import java.lang.reflect.InvocationTargetException;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.rtx.common.HttpServletRequestUtil;
import com.rtx.edi.model.base.Constant;
import com.rtx.model.dto.edi.EdiInnerRequestDTO;
import com.rtx.wms.customer.common.down.DownLoadService;
import com.rtx.wms.std.ctclass.ClassHolder;
import com.rtx.wms.std.qm.bean.RtxQMResponse;
import com.rtx.wms.std.so.bean.ApiOrders;
import com.rtx.wms.std.transer.bean.ApiTransfer;
import com.rtx.wms.std.transer.bean.ApiTransferdetail;
import com.rtx.wms.std.transer.bean.Transfer;
import com.rtx.wms.std.transer.service.ApiTransferService;
import com.rtx.wms.std.transer.service.TransferService;
import com.rtx.wms.std.validation.so.OrdersValidation;
import com.rtx.wms.std.validation.transfer.TransferValidation;

/**
 * 调拨单下发
 */
@SuppressWarnings("all")
public abstract class AbstractTransferDownHandler implements DownLoadService{

    protected Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    ApiTransferService apiTransferService;

    @Autowired
    OrdersValidation ordersValidation;

    @Autowired
    TransferService transferService;
    
    @Autowired
    TransferValidation transferValidation;

    
    

    public String create(HttpServletRequest request){
        RtxQMResponse res = new RtxQMResponse();
        ApiTransfer apiTransfer = null;
        try {
        	//处理之前
        	preHandle(request);
        	
        	String requestStr = HttpServletRequestUtil.getHttpBody(request);
    		EdiInnerRequestDTO dto = JSON.parseObject(requestStr, EdiInnerRequestDTO.class);
    		
        	if(StringUtils.hasLength(dto.getConfig().getPreconfig())) {
        		//预处理
            	preHandle(request);
        	}
        	
        	if(apiTransfer == null) {
        		String targetJson = dto.getTagetjson();
        		
        		apiTransfer = addExternalColumns(targetJson,dto);
        	}
        	
        	//处理之后
        	afterHandle(apiTransfer,requestStr);
        	
           	//校验企业级数据
        	transferValidation.checkEnterpriseConfig(Constant.ENTERPRISE, apiTransfer);
        	
        	//校验仓库级配置
        	transferValidation.check(apiTransfer.getWhseid(), apiTransfer);
        	
        	//插入之前
        	preinsert(apiTransfer,request);
        	
        	//将内部转移数据写入wms
        	insertHandle(apiTransfer);
        	
            res.setSuccess("成功");
        } catch (Exception e) {
            logger.error("调拨单：{}，创建异常：",e);
            res.setFailure(e.getMessage());
        }
        return JSON.toJSONString(res);
    }
    
    /**
     * 插入表之前处理客制化新增字段
     * @throws InvocationTargetException 
     * @throws Exception 
     * 
     */
    public ApiTransfer addExternalColumns(String targetJson,EdiInnerRequestDTO dto){
    	ApiTransfer head = null;
    	String apiid =  dto.getConfig().getTargetapiid();
    	Map<String,Class> map = ClassHolder.apiconfigClassMap.get(apiid);
    	if(map != null) {
    		Class headclass =map.get("main");
    		Class subclass =map.get("sub");
    		head = (ApiTransfer) JSON.parseObject(targetJson,headclass);
    		List<ApiTransferdetail> sub = JSON.parseArray(JSON.parseObject(targetJson).getString("details") ,subclass);
    		head.setDetails(sub);
    	}else {
    		head = JSON.parseObject(targetJson,ApiTransfer.class);
    	}

    	return head;
    }
    
    protected void insertHandle(ApiTransfer apiTransfer) {
    	LambdaQueryWrapper<Transfer> query = Wrappers.lambdaQuery();
    	query.eq(Transfer::getRtxexternkey, apiTransfer.getRtxexternkey());
    	List<Transfer> list =	transferService.queryByCondition(apiTransfer.getWhseid(), query);
    	if(list != null && list.size() > 0) {
    		throw new RuntimeException("单据"+apiTransfer.getRtxexternkey()+"，已进行仓库作业，无法修改");
    	}
    	
    	apiTransferService.addTransfer("ris_edi", apiTransfer);
    }
    
    //转换字段后处理逻辑
    protected abstract void afterHandle(ApiTransfer at,String requestStr);

    /**
     * 进入处理方法之前
     */
    protected abstract ApiOrders preHandle(HttpServletRequest request);
    
    /**
     * 在insert 之后
     * @param request
     * @return
     */
    protected abstract void preinsert(ApiTransfer at,HttpServletRequest request);

}
